const {src, dest, watch, series, parallel} = require('gulp');
const postcss = require('gulp-postcss');

// ---------------------------------
// --- Utils
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
const del = require('del');
const mode = require('gulp-mode')();
const browserSync = require('browser-sync').create();

// ---------------------------------
// --- PostCss Plugins
const rucksack = require('rucksack-css');
const postImport = require('postcss-import');
const cssnano = require("cssnano");
const autoprefixer = require("autoprefixer");
const pxtorem = require('postcss-pxtorem');
const mqpacker = require('css-mqpacker');
const minmax = require('postcss-media-minmax');
const hexrgba = require('postcss-hexrgba');

// ---------------------------------
// --- JS
const babel = require('gulp-babel');
const terser = require('gulp-terser');
const webpack = require('webpack-stream');

// ---------------------------------
// --- Pug
const pug = require('gulp-pug');
const contentData = require('gulp-data');
const fs = require('fs');

// ---------------------------------
// --- Images
const imgemin = require('gulp-image');

// ---------------------------------
// --- Clean Task
const clean = () => {
  return del(['./public'])
}
const cleanImages = () => {
  return del(['./public/assets/images'])
}
const cleanFonts = () => {
  return del(['./public/assets/fonts'])
}

// ---------------------------------
// --- CSS Task
const css = () => {
  let plugDev = [ postImport(), autoprefixer(), rucksack(), mqpacker(), minmax(), hexrgba(), pxtorem() ]
  let plugBuild = [ postImport(), autoprefixer(), rucksack(), mqpacker(), pxtorem(), minmax(), hexrgba(), cssnano() ]
  return src(['./src/style/style.css'])
    .pipe(mode.development( sourcemaps.init() ))
    .pipe(postcss(plugDev))
    .pipe(rename('app.css'))
    .pipe(mode.production( postcss(plugBuild) ))
    .pipe(mode.development( sourcemaps.write() ))
    .pipe(dest('./public/assets/css/'))
    .pipe(mode.development( browserSync.stream() ))
}

// ---------------------------------
// --- TEMPLATE Task
const views = () => {
  return src('./src/views/*.pug')
    .pipe(contentData(function (file) {
      return {
        data: JSON.parse(fs.readFileSync('src/data/data.json', 'utf8')),
      }
    }))
    .pipe(pug({
      pretty: true
    }))
    .pipe(dest('./public/'))
    .pipe(mode.development( browserSync.stream() ))
}

// ---------------------------------
// --- JS Task
const jscript = () => {
  return src('./src/js/**/*.js')
    .pipe(babel({
      presets: ['@babel/env']
    }))
    .pipe(webpack({
      mode: 'development',
      devtool: 'inline-source-map'
    }))
    .pipe(mode.development( sourcemaps.init({ loadMaps: true }) ))
    .pipe(rename('app.js'))
    .pipe(mode.production( terser({ output: { comments: false } }) ))
    .pipe(mode.development( sourcemaps.write() ))
    .pipe(dest('./public/assets/js/'))
    .pipe(mode.development( browserSync.stream() ))
}

// ---------------------------------
// --- COPY Task
const copyImages = () => {
  return src('./src/img/**/*.{jpg,jpeg,gif,png,webp,svg}')
    .pipe(mode.production(imgemin({
      optipng: ['-i 1', '-strip all', '-fix', '-o7', '-force'],
      pngquant: ['--speed=1', '--force', 256],
      zopflipng: ['-y', '--lossy_8bit', '--lossy_transparent'],
      jpegRecompress: ['--strip', '--quality', 'medium', '--min', 40, '--max', 80],
      mozjpeg: ['-optimize', '-progressive'],
      gifsicle: ['--optimize'],
      svgo: ['--enable', 'cleanupIDs', '--disable', 'convertColors']
      }))
    )
    .pipe(dest('./public/assets/img/'))
    .pipe(mode.development( browserSync.stream() ))
}

// ---------------------------------
// --- FONTS Task
const copyFonts = () => {
  return src('./src/fonts/**/*.{svg,eot,ttf,woff,woff2}')
    .pipe(dest('./public/assets/fonts'))
}

// ---------------------------------
// --- WATCH Task
const watchForChanges = () => {
  browserSync.init({
    server: {
      baseDir: './public'
    }
  });

  watch(['./src/style/**/*.css', './src/components/**/*.css'], css);
  watch('./src/js/**/*.js', jscript);
  watch('./src/img/**/*.{jpg,jpeg,gif,png,webp,svg}', series(cleanImages, copyImages));
  watch('./src/fonts/**/*.{svg,eot,ttf,woff,woff2}', series(cleanFonts, copyFonts));
  watch(['./src/views/**/*.pug', './src/components/**/*.pug', './src/data/**/*.json'], views);
  watch('./public/**/*.html').on('change', browserSync.reload);
}

// ---------------------------------
// --- PUBLIC Task
  exports.default = series(clean, parallel(css, jscript, views, copyImages, copyFonts ), watchForChanges);
  exports.build = series(clean, parallel(css, jscript, views, copyImages, copyFonts ));
